package com.ocom.payconfig.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.ocom.common.constant.PayConfigUrl;
import com.ocom.common.entity.card.*;
import com.ocom.common.entity.company.EntityCompanyInfo;
import com.ocom.common.entity.human.EntityPersonnelInfo;
import com.ocom.common.enums.ResultEnum;
import com.ocom.common.request.payconfig.repairpay.GetRepairPayConfigListRequest;
import com.ocom.common.request.payconfig.repairpay.GetRepairPayConfigRequest;
import com.ocom.common.request.payconfig.repairpay.GetRepairPayRecordListRequest;
import com.ocom.common.request.payconfig.repairpay.GetRepairPaySumRequest;
import com.ocom.common.request.payhandle.QrCodeQueryRequest;
import com.ocom.common.request.simple.SmsRequest;
import com.ocom.common.request.web.CancelOrderRequest;
import com.ocom.common.resp.Result;
import com.ocom.common.utils.AcpStateName;
import com.ocom.common.utils.DateUtils;
import com.ocom.common.utils.ResultUtil;
import com.ocom.payconfig.client.CompanyClientService;
import com.ocom.payconfig.client.MqSimpleFeign;
import com.ocom.payconfig.client.PayhandleClientService;
import com.ocom.payconfig.client.XfRecordFeign;
import com.ocom.payconfig.service.*;
import com.ocom.redis.util.RedisUtil;
import com.ocom.security.authentication.YoCiUser;
import com.ocom.security.utils.SecurityUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
public class RepairPayController {

    @Resource
    private RedisUtil redisUtil;


    @Autowired
    private XfRecordRepairpayService xfRecordRepairpayService;

    @Autowired
    private XfRecordWaitpayService xfRecordWaitpayService;

    @Autowired
    private XfRepairpayConfigService xfRepairpayConfigService;

    @Autowired
    private PersonnelInfoService personnelInfoService;

    @Autowired
    private CompanyClientService companyClientService;

    @Autowired
    private AccountController accountController;

    @Autowired
    private PayhandleClientService payhandleClientService;

    @Autowired
    private MqSimpleFeign mqSimpleFeign;

    @Autowired
    private XfRecordFeign xfRecordFeign;

    @Autowired
    private XfRecordProcessService xfRecordProcessService;


    @PostMapping(PayConfigUrl.Url_getRepairPayRecordList)
    public Result getRepairPayRecordList(@RequestBody GetRepairPayRecordListRequest request) {
        Map<Object, Object> map = new HashMap<>();
//        if (1 == request.getStatus()) {
//            PageInfo<EntityXfRecordRepairpay> xfRecordRepairpay = xfRecordRepairpayService.getXfRecordRepairpay(request.getComId(), request);
//            map.put("total", xfRecordRepairpay.getTotal());
//            map.put("list", xfRecordRepairpay.getList());
//        } else {
//        }
        PageInfo<EntityXfRecordWaitpay> xfRecordWaitpay = xfRecordWaitpayService.getXfRecordWaitpay(request.getComId(), false, request);
        map.put("total", xfRecordWaitpay.getTotal());

        List<EntityXfRecord> list=JSON.parseArray(JSON.toJSONString(xfRecordWaitpay.getList()),EntityXfRecord.class);
        for (EntityXfRecord entityXfRecord : list) {
            String paymentType= String.valueOf(entityXfRecord.getOpTypeDiff());
            String opType= String.valueOf(entityXfRecord.getOpType());
            int paymentTypes= Integer.parseInt(paymentType);
            entityXfRecord.setAmountType(AcpStateName.getConsName(entityXfRecord.getConsState(),paymentTypes,Integer.parseInt(opType)));
        }
        map.put("list", list);
        return ResultUtil.success(map);
    }

    @PostMapping(PayConfigUrl.Url_getRepairPayConfig)
    public Result getRepairPayConfig(@RequestBody GetRepairPayConfigRequest request) {
        return ResultUtil.success(xfRepairpayConfigService.getByComId(request.getComId()));
    }

    @PostMapping(PayConfigUrl.Url_getRepairPayConfigList)
    public Result getRepairPayConfigList(@RequestBody GetRepairPayConfigListRequest request) {
        return ResultUtil.success(xfRepairpayConfigService.getListByStatus(request.getStatus()));
    }


    @PostMapping(PayConfigUrl.Url_addRepairPayConfig)
    public Result addRepairPayConfig(@RequestBody EntityXfRepairpayConfig request) {
        YoCiUser yoCiUser = SecurityUtils.getYoCiUser();
        request.setComId(yoCiUser.getComId());
        xfRepairpayConfigService.removeById(request.getComId());
        xfRepairpayConfigService.save(request);
        String canKey = "xf_repairpay_config#comId:"+ request.getComId();
        redisUtil.dels(canKey);
        return ResultUtil.success();
    }

    @PostMapping(PayConfigUrl.Url_saveXfRecordRepairpay)
    public Result saveXfRecordRepairpay(@RequestBody EntityXfRecordRepairpay request) {
        return ResultUtil.success(xfRecordRepairpayService.save(request.getComId(), request));
    }

    @PostMapping(PayConfigUrl.Url_RepairpayRemoveById)
    public Result repairpayRemoveById(@RequestBody EntityXfRecordWaitpay request) {
        return ResultUtil.success(xfRecordWaitpayService.removeById(request.getComId(), request.getId()));
    }

    @PostMapping(PayConfigUrl.Url_RepairpayUpdatePayState)
    public Result updatePayState(@RequestBody EntityXfRecordWaitpay request) {
        return ResultUtil.success(xfRecordWaitpayService.updatePayState(request.getComId(), request));
    }

    @PostMapping(PayConfigUrl.Url_getRepairPaySum)
    public Result getRepairPaySum(@RequestBody GetRepairPaySumRequest request) {
        return ResultUtil.success(xfRecordWaitpayService.getRepairPaySum(request.getComId(), request.getPId()));
    }

    @PostMapping(PayConfigUrl.Url_RepairPayPageTimedSMS)
    public Result repairPayPageTimedSMS() {
        Date now = new Date();
        String staticHour = "20:00";
        String hour = DateUtils.getStrDate(now, "HH:mm");
        log.info("补缴定时短信通知开始执行，当前时间：【{}】,当前小时：【{}】", now, hour);
        List<EntityXfRepairpayConfig> repairpayConfigs = xfRepairpayConfigService.getListByStatus(1);
        for (EntityXfRepairpayConfig configInfo : repairpayConfigs) {
            List<EntityXfRecordWaitpay> repairPaySums = xfRecordWaitpayService.getRepairPaySum(configInfo.getComId(), null);
            for (EntityXfRecordWaitpay sumInfo : repairPaySums) {
                if (sumInfo.getDays().equals(configInfo.getAllowDays())) {
                    //最后一套，发送冻结短信倒计时通知
                    sendSms(1, sumInfo);
                    if (staticHour.equals(hour)) {
                        //如果当前时间为20点则发送冻结短信通知，并冻结账户（调用3.0微服务-消费配置 4.3修改账号信息(updateXFAccount)，accountState=1），跳过本次循环；
                        EntityXfAccountInfo accountInfo = new EntityXfAccountInfo();
                        try {
                            accountInfo.setPId(sumInfo.getPId());
                            accountInfo.setComId(sumInfo.getComId());
                            accountInfo.setAccountState(1);
                            accountController.UpdateXFAccount(accountInfo);
                            log.info("未补缴！冻结账户：【{}】", accountInfo);
                        } catch (Exception e) {
                            e.printStackTrace();
                            log.info("冻结账户失败：【{}】", accountInfo);
                        }
                        sendSms(2, sumInfo);
                    }
                } else if (1 == configInfo.getIfTimedSms() && staticHour.equals(configInfo.getTimedSms())) {
                    //日常，发送短信通知
                    sendSms(3, sumInfo);
                }
            }
        }
        return ResultUtil.success();
    }

    @PostMapping(PayConfigUrl.Url_RepairPayPageUpdatePayStatus)
    public Result repairPayPageUpdatePayStatus(@RequestParam("startComId") Long startComId) {
        GetRepairPayRecordListRequest request = new GetRepairPayRecordListRequest();
        request.setStatus(4);
        request.setPayState(0);
        PageInfo<EntityXfRecordWaitpay> xfRecordWaitpay = xfRecordWaitpayService.getXfRecordWaitpay(startComId, true, request);
        List<EntityXfRecordWaitpay> recordWaitpayList = xfRecordWaitpay.getList();

        for (EntityXfRecordWaitpay waitpay : recordWaitpayList) {
            try {
                List<EntityXfRecordProcess> entityXfRecordProcesses = xfRecordProcessService.selectPlatOrderNo(waitpay.getComId(), waitpay.getOrderNo());
                HashMap<String, JSONObject> map = new HashMap<>();
                for (EntityXfRecordProcess recordProcess : entityXfRecordProcesses) {
                    try {
                        QrCodeQueryRequest qrCodeQueryRequest = new QrCodeQueryRequest();
                        qrCodeQueryRequest.setCompanyId(recordProcess.getComId());
                        qrCodeQueryRequest.setTradeNo(recordProcess.getOrderNo());
                        qrCodeQueryRequest.setMachNo(recordProcess.getDeviceNo());
                        Result payQuery = payhandleClientService.onlinePayQuery(qrCodeQueryRequest);
                        log.info("【{}】 支付结果：【{}】", recordProcess.getOrderNo(), payQuery);
                        if (200 == payQuery.getCode()) {
                            JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(payQuery.getData()));
                            map.put("success", jsonObject);
                        } else if (ResultEnum.Err_3030.getKey().equals(payQuery.getCode())) {
                            map.put("failed", new JSONObject());
                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                        log.info("【{}】 循环处理补缴结果：【{}】", waitpay.getOrderNo(), e.getMessage());
                    }
                }

                JSONObject success = map.get("success");
                JSONObject failed = map.get("failed");
                if (null != success) {
                    waitpay.setPayState(1);
                    waitpay.setPayTime(success.getDate("orderTime"));
                } else if (null != failed) {
                    waitpay.setPayState(2);
                }
                boolean b = xfRecordWaitpayService.updatePayState(waitpay.getComId(), waitpay);
                log.info("更新待补缴订单【{}】,【{}】", waitpay.getOrderNo(), b);

                List<EntityXfRecordWaitpay> repairPaySum = xfRecordWaitpayService.getRepairPaySum(waitpay.getComId(), waitpay.getPId());
                log.info("【{}】 repairPaySum结果：【{}】", waitpay.getOrderNo(), repairPaySum);
                if (null == repairPaySum || 0 == repairPaySum.size() || 0 == repairPaySum.get(0).getAmount()) {
                    Result account = accountController.GetXFAccount(waitpay.getComId(), waitpay.getPId().intValue(),-1);
                    if (200 == account.getCode()) {
                        EntityXfAccountInfo entityXfAccountInfo = JSON.parseObject(JSON.toJSONString(account.getData()), EntityXfAccountInfo.class);
                        entityXfAccountInfo.setAccountState(0);
                        Result result = accountController.UpdateXFAccount(entityXfAccountInfo);
                        log.info("修改账户状态成功【{}】,【{}】", result, entityXfAccountInfo);
                    } else {
                        log.info("修改账户状态失败【{}】", account);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return ResultUtil.success();
    }


    private void sendSms(int type, EntityXfRecordWaitpay entityXfRecordWaitpay) {
        try {
            SmsRequest request = new SmsRequest();

            request.setSecretId("AKIDcLzhN0a8e8eChEnaQG8zpifcabfnu5JX");
            request.setSecretKey("Kh6VozznPn13ECwSlphN9jCVaRLTPIPa");
            request.setSignName("鑫澳康科技");
            request.setSdkAppId("1400314290");

            request.setTemplateId("2051614");

            EntityPersonnelInfo onePersonInfo = personnelInfoService.getOnePersonInfo(entityXfRecordWaitpay.getComId(), entityXfRecordWaitpay.getPId());
            HashMap<String, Object> map = new HashMap<>();
            map.put("comId", entityXfRecordWaitpay.getComId());
            Result getCompanyInfo = companyClientService.GetCompanyInfo(map);

            if (null == onePersonInfo || 200 != getCompanyInfo.getCode() || null == getCompanyInfo.getData() || StringUtils.isBlank(onePersonInfo.getPPhone())) {
                log.info("补缴短信发生失败，人员或学校不存在！ 【{}】.人员【{}】,学校【{}】", entityXfRecordWaitpay, onePersonInfo, getCompanyInfo);

            } else {

                EntityCompanyInfo companyInfo = JSON.parseObject(JSON.toJSONString(getCompanyInfo.getData()), EntityCompanyInfo.class);

                request.setPhone(onePersonInfo.getPPhone());

                request.getParams().add(companyInfo.getComName());
                request.getParams().add(String.valueOf(entityXfRecordWaitpay.getTimes()));
                request.getParams().add(String.valueOf(entityXfRecordWaitpay.getAmount()));
                try {
                    log.info("发送补缴短信 【{}】", request);
                    Result result = mqSimpleFeign.FySms(request);
                    log.info("发送补缴短信结果 【{}】", result);
                } catch (Exception e) {
                    e.printStackTrace();
                    log.info("发送短信异常 【{}】", e);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            log.info("补缴短信发生失败：【{}】", e);

        }

    }

    @PostMapping(PayConfigUrl.Url_RepairPayCancle)
    public Result repairPayCancel(@RequestBody CancelOrderRequest request) {
        EntityXfRecordWaitpay entity = new EntityXfRecordWaitpay();
        entity.setPayState(4);
        entity.setPayTime(new Date());
        entity.setOrderNo(request.getOrderNo());
        boolean bo = xfRecordWaitpayService.updatePayState(request.getComId(), entity);
        if (bo) return ResultUtil.success();
        return ResultUtil.error(ResultEnum.Err_3014);
    }


}
